#include <iostream>
#include <pthread.h>
#include <unistd.h>

using namespace std;

static void printTid(const char* name, const pthread_t& tid)
{
    printf("%s 正在运行，thread id: 0x%x\n", name, tid);
}

void* startRoutine(void* args)
{
    const char* name = static_cast<const char*>(args);
    int cnt = 5;
    while (true)
    {
        // cout << "线程正在运行..." << endl;
        printTid(name, pthread_self());
        sleep(1);

        // if (cnt-- == 0) break;

        // if (cnt-- == 0)
        // {
        //     int* p = nullptr;
        //     *p = 100; // 野指针问题
        // }
    }

    // 新线程运行5s后退出
    cout << "线程退出啦……" << endl;
    // 1. 线程退出的方式: return
    // 通过pthread_join获得这个函数的返回值
    // 返回值是个void*，所以为了拿到这个void*需要传进去void**
    // 一个输出型参数
    
    // 2. 线程退出方式，pthread_exit
    pthread_exit((void*)111);

    // return (void*)10;
}

int main()
{
    pthread_t tid;
    int n = pthread_create(&tid, nullptr, startRoutine, (void*)"thread1");
    // 代表main thread对应的工作，一创建就取消
    sleep(3);

    // 3. 线程退出方式，给线程发送取消请求，如果线程是被取消的，退出结果是: -1
    pthread_cancel(tid);
    cout << "new thread been canceled" << endl;

    // cout << "new thread id: " << tid << endl; // 线程ID -- 为什么这么大？
    // PTHREAD_CANCELED;
    
    // 主线程运行10s后退
    // sleep(10);
    // 线程退出的时候，一般必须要进行join，如果不进行join
    // 就会造成类似于进程那样的内存泄漏的问题（没有僵尸线程这样的说法）
    // 线程对应的退出结果暂时不获取

    void* ret = nullptr;
    pthread_join(tid, &ret); // void** retval是一个输出型参数
    cout << "main thread join success, *ret: " << (long long)ret << endl;
    // sleep(10);

    while (true)
    {
        cout << "main thread 正在运行..." << endl;
        printTid("main thread", pthread_self());
        sleep(1);
    }

    return 0;
}

// 新线程被创建出来5s后就会退，退出之后，看到的线程对应的信息应该是还有的
// 因为还没有被join，5s后被join后当我们主线程开始打印消息时，说明join完成
// 我们看到的现象是线程退出时，查看时却少了一个，预期应该是两个线程，应该等到join之后才变成一个线程
// ps命令在查的时候，那种退出的线程就不显示了
